/* Copyright (c) 2008 Google Inc.
*  Copyright (c) 2009 Pierre Henri Kuate.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace org.opensocial.client
{
    public class Gadget
    {
        public string ConsumerSecret { get; set; }
        public string OutgoingConsumerKey { get; set; }
        public OpenSocialProvider Container { get; set; }
    }

    public class SessionManager
    {
        private class SessionCollection : System.Collections.Generic.Dictionary<System.Guid, OpenSocialClient> // TODO: Use SynchronizedKeyedCollection?
        {
            /*protected override System.Guid GetKeyForItem(OpenSocialClient item)
            {
                return item.Id;
            }*/
        }
        private static readonly SessionCollection _proxiedSessions = new SessionCollection(); // TODO: Does it need to be synchronized? (thread-safe)


        private static System.Web.SessionState.HttpSessionState State
        {
            get { return System.Web.HttpContext.Current == null ? null : System.Web.HttpContext.Current.Session; }
        }

        public static bool IsAuthenticated
        {
            get { return State != null && State["OpenSocial.Client"] is OpenSocialClient; }
        }

        public static OpenSocialClient Client
        {
            get { return (OpenSocialClient)State["OpenSocial.Client"]; }
            set { State["OpenSocial.Client"] = value; }
        }

        public static bool CreateSession(System.Web.HttpRequest request, System.Collections.Generic.Dictionary<string, Gadget> knownGadgets, out OpenSocialClient client)
        {
            if (!OpenSocialRequestValidator.verifyHmacSignature(request, knownGadgets, out client))
                return false;

            _proxiedSessions.Add(client.Id, client); // Keep it here until the IFrame is loaded and ExtractSession removes it
            return true;
        }

        public static void AddClient(OpenSocialClient client) // TODO: Remove when OpenSocialRequestValidator.verifyHmacSignature() works
        {
            _proxiedSessions.Add(client.Id, client);
        }

        public static void WriteIFrame(string requestUrl, System.Web.HttpResponse response, OpenSocialClient client)
        {
            var url = requestUrl;
            var index = url.IndexOf("?");
            if (index > 0) // TODO: else: The signature was not verified.
                url = url.Substring(0, index); // Remove the QueryString
            response.ClearContent();
            response.Output.Write("<iframe style='width:100%;height:100%;margin:0;' frameborder='0' src='"
                + url + "?opensocial_session_id=" + client.Id.ToString("N") + "' />");
            response.End();
        }

        public static bool ExtractSession(System.Web.HttpRequest request)
        {
            if (!string.IsNullOrEmpty(request.QueryString["opensocial_session_id"]))
            {
                var id = new System.Guid(request.QueryString["opensocial_session_id"]);
                if (_proxiedSessions.ContainsKey(id)) // TODO: else: Trying to hack?
                {
                    Client = _proxiedSessions[id]; // Transfer from the static list to the ASP.NET Session
                    _proxiedSessions.Remove(id);
                }
            }
            return IsAuthenticated;
        }
    }
}